#include <tasks_manager/msg_convert.h>

/*******************************************
 * v3_msgs 消息数据转换
 *******************************************/

// TaskType -> v3_msgs::TaskType
v3_msgs::TaskType MsgConvert::TaskType2V3Msgs(TaskType task_type){
    v3_msgs::TaskType task_type_v3;
    switch(task_type){
        case TaskType::CHARGING_TASK:
            task_type_v3.type = task_type_v3.CHARGING_TASK;
            break;
        case TaskType::P2P_TASK:
            task_type_v3.type = task_type_v3.P2P_TASK;
            break;
        case TaskType::TEACH_TASK:
            task_type_v3.type = task_type_v3.TEACH_TASK;
            break;
        case TaskType::SWEEP_TASK:
            task_type_v3.type = task_type_v3.SWEEP_TASK;
            break;
        case TaskType::ELEVATOR_TRANS_TASK:
            task_type_v3.type = task_type_v3.ELEVATOR_TRANS_TASK;
            break;
        default:    // 默认值 CHARGING_TASK
            task_type_v3.type = task_type_v3.SWEEP_TASK;
            break;
    }
    return task_type_v3;
}

// v3_msgs::TaskType -> TaskType
TaskType MsgConvert::V3Msgs2TaskType(v3_msgs::TaskType task_type_v3){
    TaskType task_type;
    switch(task_type_v3.type){
        case v3_msgs::TaskType::CHARGING_TASK:
            task_type = TaskType::CHARGING_TASK;
            break;
        case v3_msgs::TaskType::P2P_TASK:
            task_type = TaskType::P2P_TASK;
            break;
        case v3_msgs::TaskType::TEACH_TASK:
            task_type = TaskType::TEACH_TASK;
            break;
        case v3_msgs::TaskType::SWEEP_TASK:
            task_type = TaskType::SWEEP_TASK;
            break;
        case v3_msgs::TaskType::ELEVATOR_TRANS_TASK:
            task_type = TaskType::ELEVATOR_TRANS_TASK;
            break;
        default:    // 默认值 CHARGING_TASK
            task_type = TaskType::SWEEP_TASK;
            break;
    }
    return task_type;
}

// TaskState -> v3_msgs::TaskState
v3_msgs::TaskState MsgConvert::TaskStatus2V3Msgs(TaskState task_status){
    v3_msgs::TaskState task_status_v3;
    switch(task_status){
        case TaskState::IDLE:
            task_status_v3.status = task_status_v3.IDLE;
            break;
        case TaskState::EXECUING:
            task_status_v3.status = task_status_v3.EXECUING;
            break;
        case TaskState::PAUSE:
            task_status_v3.status = task_status_v3.PAUSE;
            break;
        case TaskState::BLOCKED:
            task_status_v3.status = task_status_v3.BLOCKED;
            break;
        case TaskState::FINISHED:
            task_status_v3.status = task_status_v3.FINISHED;
            break;
        case TaskState::USER_CANCEL:
            task_status_v3.status = task_status_v3.USER_CANCEL;
            break;
        case TaskState::TERMINATED:
            task_status_v3.status = task_status_v3.TERMINATED;
            break;
        case TaskState::ERROR:
            task_status_v3.status = task_status_v3.ERROR;
            break;
        case TaskState::UNKNOWN:
            task_status_v3.status = task_status_v3.UNKNOWN;
            break;
        default:    // 默认值 UNKNOWN
            task_status_v3.status = task_status_v3.UNKNOWN;
            break;
    }
    return task_status_v3;
}

// v3_msgs::TaskState -> TaskState
TaskState MsgConvert::V3Msgs2TaskStatus(v3_msgs::TaskState task_status_v3){
    TaskState task_status;
    switch(task_status_v3.status){
        case v3_msgs::TaskState::IDLE:
            task_status = TaskState::IDLE;
            break;
        case v3_msgs::TaskState::EXECUING:
            task_status = TaskState::EXECUING;
            break;
        case v3_msgs::TaskState::PAUSE:
            task_status = TaskState::PAUSE;
            break;
        case v3_msgs::TaskState::BLOCKED:
            task_status = TaskState::BLOCKED;
            break;
        case v3_msgs::TaskState::FINISHED:
            task_status = TaskState::FINISHED;
            break;
        case v3_msgs::TaskState::USER_CANCEL:
            task_status = TaskState::USER_CANCEL;
            break;
        case v3_msgs::TaskState::TERMINATED:
            task_status = TaskState::TERMINATED;
            break;
        case v3_msgs::TaskState::ERROR:
            task_status = TaskState::ERROR;
            break;
        case v3_msgs::TaskState::UNKNOWN:
            task_status = TaskState::UNKNOWN;
            break;
        default:    // 默认值 UNKNOWN
            task_status = TaskState::UNKNOWN;
            break;
    }
    return task_status;
}

// EdgeMode -> v3_msgs::EdgeMode
v3_msgs::EdgeMode MsgConvert::EdgeMode2V3Msgs(EdgeMode edge_mode){
    v3_msgs::EdgeMode edge_mode_v3;
    switch(edge_mode){
        case EdgeMode::EDGE_ZERO_MODE:
            edge_mode_v3.mode = edge_mode_v3.EDGE_ZERO_MODE;
            break;
        case EdgeMode::EDGE_5CM_MODE:
            edge_mode_v3.mode = edge_mode_v3.EDGE_5CM_MODE;
            break;
        case EdgeMode::UNKNOWN:
            edge_mode_v3.mode = edge_mode_v3.UNKNOWN;
            break;
        default:    
            edge_mode_v3.mode = edge_mode_v3.UNKNOWN;
    }
    return edge_mode_v3;
}

// v3_msgs::EdgeMode -> EdgeMode
EdgeMode MsgConvert::V3Msgs2EdgeMode(v3_msgs::EdgeMode edge_mode_v3){
    EdgeMode edge_mode;
    switch(edge_mode_v3.mode){
        case v3_msgs::EdgeMode::EDGE_ZERO_MODE:
            edge_mode = EdgeMode::EDGE_ZERO_MODE;
            break;
        case v3_msgs::EdgeMode::EDGE_5CM_MODE:
            edge_mode = EdgeMode::EDGE_5CM_MODE;
            break;
        case v3_msgs::EdgeMode::UNKNOWN:
            edge_mode = EdgeMode::UNKNOWN;
            break;
        default:    
            edge_mode = EdgeMode::UNKNOWN;
            break;
    }
    return edge_mode;
}

// TaskControlMode -> v3_msgs::TaskControlMode
v3_msgs::TaskControlMode MsgConvert::TaskControlMode2V3Msgs(TaskControlMode task_control_mode){
    v3_msgs::TaskControlMode task_control_mode_v3;
    switch(task_control_mode){
        case TaskControlMode::SWEEP_STANDARD_MODE:
            task_control_mode_v3.mode = task_control_mode_v3.SWEEP_STANDARD_MODE;
            break;
        case TaskControlMode::SWEEP_EDGE_MODE:
            task_control_mode_v3.mode = task_control_mode_v3.SWEEP_EDGE_MODE;
            break;
        case TaskControlMode::SWEEP_STANDARD_AND_EDGE:
            task_control_mode_v3.mode = task_control_mode_v3.SWEEP_STANDARD_AND_EDGE;
            break;
        case TaskControlMode::FOLLOW_MODE:
            task_control_mode_v3.mode = task_control_mode_v3.FOLLOW_MODE;
            break;
        // case TaskControlMode::P2P_MODE:
        //     task_control_mode_v3.mode = task_control_mode_v3.P2P_MODE;
        //     break;
        // case TaskControlMode::CHARGING_MODE:
        //     task_control_mode_v3.mode = task_control_mode_v3.CHARGING_MODE;
        //     break;
        // case TaskControlMode::ELEVATOR_TRANS_MODE:
        //     task_control_mode_v3.mode = task_control_mode_v3.ELEVATOR_TRANS_MODE;
        //     break;
        // case TaskControlMode::SWEEP_STANDARD_AND_REPAIR:
        //     task_control_mode_v3.mode = task_control_mode_v3.SWEEP_STANDARD_AND_REPAIR;
        //     break;
        default:    
            task_control_mode_v3.mode = task_control_mode_v3.SWEEP_STANDARD_MODE;
            break;
    }
    return task_control_mode_v3;
}

// v3_msgs::TaskControlMode -> TaskControlMode
TaskControlMode MsgConvert::V3Msgs2TaskControlMode(v3_msgs::TaskControlMode task_control_mode_v3){
    TaskControlMode task_control_mode;
    switch(task_control_mode_v3.mode){
        case v3_msgs::TaskControlMode::SWEEP_STANDARD_MODE:
            task_control_mode = TaskControlMode::SWEEP_STANDARD_MODE;
            break;
        case v3_msgs::TaskControlMode::SWEEP_EDGE_MODE:
            task_control_mode = TaskControlMode::SWEEP_EDGE_MODE;
            break;
        case v3_msgs::TaskControlMode::SWEEP_STANDARD_AND_EDGE:
            task_control_mode = TaskControlMode::SWEEP_STANDARD_AND_EDGE;
            break;
        // case v3_msgs::TaskControlMode::SWEEP_STANDARD_AND_REPAIR:
        //     task_control_mode = TaskControlMode::SWEEP_STANDARD_AND_REPAIR;
        //     break;
        case v3_msgs::TaskControlMode::FOLLOW_MODE:
            task_control_mode = TaskControlMode::FOLLOW_MODE;
            break;
        // case v3_msgs::TaskControlMode::P2P_MODE:
        //     task_control_mode = TaskControlMode::P2P_MODE;
        //     break;
        // case v3_msgs::TaskControlMode::CHARGING_MODE:
        //     task_control_mode = TaskControlMode::CHARGING_MODE;
        //     break;
        // case v3_msgs::TaskControlMode::ELEVATOR_TRANS_MODE:
        //     task_control_mode = TaskControlMode::ELEVATOR_TRANS_MODE;
        //     break;
        default:    
            task_control_mode = TaskControlMode::SWEEP_STANDARD_MODE;
            break;
    }
    return task_control_mode;
}


// TaskSpeed -> v3_msgs::TaskSpeed
v3_msgs::TaskSpeed MsgConvert::TaskSpeed2V3Msgs(TaskSpeed task_speed){
    v3_msgs::TaskSpeed task_speed_v3;
    switch(task_speed){
        case TaskSpeed::LOW_SPEED:
            task_speed_v3.speed = task_speed_v3.LOW_SPEED;
            break;
        case TaskSpeed::MIDDLE_SPEED:
            task_speed_v3.speed = task_speed_v3.MIDDLE_SPEED;
            break;
        case TaskSpeed::HIGH_SPEED:
            task_speed_v3.speed = task_speed_v3.HIGH_SPEED;
            break;
        default:    
            task_speed_v3.speed = task_speed_v3.LOW_SPEED;
            break;
    }
    return task_speed_v3;
}


// v3_msgs::TaskSpeed -> TaskSpeed
TaskSpeed MsgConvert::V3Msgs2TaskSpeed(v3_msgs::TaskSpeed task_speed_v3){
    TaskSpeed task_speed;
    switch(task_speed_v3.speed){
        case v3_msgs::TaskSpeed::LOW_SPEED:
            task_speed = TaskSpeed::LOW_SPEED;
            break;
        case v3_msgs::TaskSpeed::MIDDLE_SPEED:
            task_speed = TaskSpeed::MIDDLE_SPEED;
            break;
        case v3_msgs::TaskSpeed::HIGH_SPEED:
            task_speed = TaskSpeed::HIGH_SPEED;
            break;
        default:    
            task_speed = TaskSpeed::LOW_SPEED;
            break;
    }
    return task_speed;
}

// PathGenerateType -> v3_msgs::PathGenerateType
v3_msgs::PathGenerateType MsgConvert::PathGenerateType2V3Msgs(PathGenerateType path_generate_type){
    v3_msgs::PathGenerateType path_generate_type_v3;
    switch(path_generate_type){
        case PathGenerateType::BOUSTROPHEDON_METHOD:
            path_generate_type_v3.type = path_generate_type_v3.BOUSTROPHEDON_METHOD;
            break;
        case PathGenerateType::ARC_BOUSTROPHEDON_METHOD:
            path_generate_type_v3.type = path_generate_type_v3.ARC_BOUSTROPHEDON_METHOD;
            break;
        case PathGenerateType::WRAPPER_METHOD:
            path_generate_type_v3.type = path_generate_type_v3.WRAPPER_METHOD;
            break;
        case PathGenerateType::EDGE_METHOD:
            path_generate_type_v3.type = path_generate_type_v3.EDGE_METHOD;
            break;
        case PathGenerateType::P2P_METHOD:
            path_generate_type_v3.type = path_generate_type_v3.P2P_METHOD;
            break;
        case PathGenerateType::MANUAL_METHOD:
            path_generate_type_v3.type = path_generate_type_v3.MANUAL_METHOD;
            break;
        case PathGenerateType::MANUAL_POLYGON_METHOD:
            path_generate_type_v3.type = path_generate_type_v3.MANUAL_POLYGON_METHOD;
            break;
        default:    
            path_generate_type_v3.type = path_generate_type_v3.BOUSTROPHEDON_METHOD;
            break;
    }
    return path_generate_type_v3;
}

// v3_msgs::PathGenerateType -> PathGenerateType
PathGenerateType MsgConvert::V3Msgs2PathGenerateType(v3_msgs::PathGenerateType path_generate_type_v3){
    PathGenerateType path_generate_type;
    switch(path_generate_type_v3.type){
        case v3_msgs::PathGenerateType::BOUSTROPHEDON_METHOD:
            path_generate_type = PathGenerateType::BOUSTROPHEDON_METHOD;
            break;
        case v3_msgs::PathGenerateType::ARC_BOUSTROPHEDON_METHOD:
            path_generate_type = PathGenerateType::ARC_BOUSTROPHEDON_METHOD;
            break;
        case v3_msgs::PathGenerateType::WRAPPER_METHOD:
            path_generate_type = PathGenerateType::WRAPPER_METHOD;
            break;
        case v3_msgs::PathGenerateType::EDGE_METHOD:
            path_generate_type = PathGenerateType::EDGE_METHOD;
            break;
        case v3_msgs::PathGenerateType::P2P_METHOD:
            path_generate_type = PathGenerateType::P2P_METHOD;
            break;
        case v3_msgs::PathGenerateType::MANUAL_METHOD:
            path_generate_type = PathGenerateType::MANUAL_METHOD;
            break;
        case v3_msgs::PathGenerateType::MANUAL_POLYGON_METHOD:
            path_generate_type = PathGenerateType::MANUAL_POLYGON_METHOD;
            break;
        default:    
            path_generate_type = PathGenerateType::BOUSTROPHEDON_METHOD;
            break;
    }
    return path_generate_type;
}


// PathGenerateAction -> v3_msgs::PathGenerateAction
v3_msgs::PathGenerateAction MsgConvert::PathGenerateAction2V3Msgs(PathGenerateAction path_generate_action){
    v3_msgs::PathGenerateAction path_generate_action_v3;
    switch(path_generate_action){
        case PathGenerateAction::UNKNOWN:
            path_generate_action_v3.data = path_generate_action_v3.UNKNOWN;
            break;
        case PathGenerateAction::START_RECORD:
            path_generate_action_v3.data = path_generate_action_v3.START_RECORD;
            break;
        case PathGenerateAction::FINISHED_RECORD:
            path_generate_action_v3.data = path_generate_action_v3.FINISHED_RECORD;
            break;
        case PathGenerateAction::CANCEL_RECORD:
            path_generate_action_v3.data = path_generate_action_v3.CANCEL_RECORD;
            break;
        default:    
            path_generate_action_v3.data = path_generate_action_v3.UNKNOWN;
            break;
    }
    return path_generate_action_v3;
}

// v3_msgs::PathGenerateAction -> PathGenerateAction
PathGenerateAction MsgConvert::V3Msgs2PathGenerateAction(v3_msgs::PathGenerateAction path_generate_action_v3){
    PathGenerateAction path_generate_action;
    switch(path_generate_action_v3.data){
        case v3_msgs::PathGenerateAction::UNKNOWN:
            path_generate_action = PathGenerateAction::UNKNOWN;
            break;
        case v3_msgs::PathGenerateAction::START_RECORD:
            path_generate_action = PathGenerateAction::START_RECORD;
            break;
        case v3_msgs::PathGenerateAction::FINISHED_RECORD:
            path_generate_action = PathGenerateAction::FINISHED_RECORD;
            break;
        case v3_msgs::PathGenerateAction::CANCEL_RECORD:
            path_generate_action = PathGenerateAction::CANCEL_RECORD;
            break;
        default:    
            path_generate_action = PathGenerateAction::UNKNOWN;
            break;
    }
    return path_generate_action;
}

// DeviceType -> v3_msgs::DeviceType
v3_msgs::DeviceType MsgConvert::DeviceType2V3Msgs(DeviceType device_type){
    v3_msgs::DeviceType device_type_v3;
    switch(device_type){
        case DeviceType::SWEEP_DEVICE:
            device_type_v3.type = device_type_v3.SWEEP_DEVICE;
            break;
        case DeviceType::WASH_DEVICE:
            device_type_v3.type = device_type_v3.WASH_DEVICE;
            break;
        default:    
            device_type_v3.type = device_type_v3.SWEEP_DEVICE;
            break;
    }
    return device_type_v3;
}

// v3_msgs::DeviceType -> DeviceType
DeviceType MsgConvert::V3Msgs2DeviceType(v3_msgs::DeviceType device_type_v3){
    DeviceType device_type;
    switch(device_type_v3.type){
        case v3_msgs::DeviceType::SWEEP_DEVICE:
            device_type = DeviceType::SWEEP_DEVICE;
            break;
        case v3_msgs::DeviceType::WASH_DEVICE:
            device_type = DeviceType::WASH_DEVICE;
            break;
        default:    
            device_type = DeviceType::SWEEP_DEVICE;
            break;
    }
    return device_type;
}

// TaskPath -> v3_msgs::TaskPath
v3_msgs::TaskPath MsgConvert::TaskPath2V3Msgs(TaskPath task_path){
    v3_msgs::TaskPath task_path_v3;
    task_path_v3.path_type = PathGenerateType2V3Msgs(task_path.path_type);
    task_path_v3.poses = task_path.poses;
    task_path_v3.path_interval = task_path.path_interval;
    return task_path_v3;
}

// v3_msgs::TaskPath -> TaskPath
TaskPath MsgConvert::V3Msgs2TaskPath(v3_msgs::TaskPath task_path_v3){
    TaskPath task_path;
    task_path.path_type = V3Msgs2PathGenerateType(task_path_v3.path_type);
    task_path.poses = task_path_v3.poses;
    task_path.path_interval = task_path_v3.path_interval;
    return task_path;
}

// TaskBase -> v3_msgs::TaskBase
v3_msgs::TaskBase MsgConvert::TaskBase2V3Msgs(TaskBase task_base){
    v3_msgs::TaskBase task_base_v3;
    task_base_v3.task_name = task_base.task_name;
    task_base_v3.task_id = task_base.task_id;
    task_base_v3.map_base = task_base.map_base;
    task_base_v3.next_map_base = task_base.next_map_base;
    task_base_v3.group_name = task_base.group_name;
    task_base_v3.group_id = task_base.group_id;
    task_base_v3.task_type = TaskType2V3Msgs(task_base.task_type);
    task_base_v3.start = task_base.start;
    task_base_v3.polygon = task_base.polygon;
    task_base_v3.device_type = DeviceType2V3Msgs(task_base.device_type);
    task_base_v3.control_mode = TaskControlMode2V3Msgs(task_base.control_mode);
    task_base_v3.edge_mode = EdgeMode2V3Msgs(task_base.edge_mode);
    task_base_v3.task_speed = TaskSpeed2V3Msgs(task_base.task_speed);
    for(auto& path : task_base.paths){
        task_base_v3.paths.emplace_back(TaskPath2V3Msgs(path));
    }
    for(auto& path : task_base.edge_paths){
        task_base_v3.edge_paths.emplace_back(TaskPath2V3Msgs(path));
    }
    task_base_v3.pose = task_base.pose;
    task_base_v3.dynamic_adjust_path = task_base.dynamic_adjust_path;
    task_base_v3.utils_mode = task_base.utils_mode;
    task_base_v3.estimated_time = task_base.estimated_time;
    task_base_v3.estimated_distance = task_base.estimated_distance;
    task_base_v3.estimated_speed = task_base.estimated_speed;
    task_base_v3.estimated_efficiency = task_base.estimated_efficiency;
    task_base_v3.task_area = task_base.task_area;
    task_base_v3.path_gen = PathGenerate2V3Msgs(task_base.path_gen);
    task_base_v3.is_top = task_base.is_top;
    task_base_v3.is_assigned = task_base.is_assigned;
    return task_base_v3;
}

// v3_msgs::TaskBase -> TaskBase
TaskBase MsgConvert::V3Msgs2TaskBase(v3_msgs::TaskBase task_base_v3){
    TaskBase task_base;
    task_base.task_name = task_base_v3.task_name;
    task_base.task_id = task_base_v3.task_id;
    task_base.map_base = task_base_v3.map_base;
    task_base.next_map_base = task_base_v3.next_map_base;
    task_base.group_name = task_base_v3.group_name;
    task_base.group_id = task_base_v3.group_id;
    task_base.task_type = V3Msgs2TaskType(task_base_v3.task_type);
    task_base.start = task_base_v3.start;
    task_base.polygon = task_base_v3.polygon;
    task_base.device_type = V3Msgs2DeviceType(task_base_v3.device_type);
    task_base.control_mode = V3Msgs2TaskControlMode(task_base_v3.control_mode);
    task_base.edge_mode = V3Msgs2EdgeMode(task_base_v3.edge_mode);
    task_base.task_speed = V3Msgs2TaskSpeed(task_base_v3.task_speed);
    for(auto& path_v3 : task_base_v3.paths){
        task_base.paths.emplace_back(V3Msgs2TaskPath(path_v3));
    }
    for(auto& path_v3 : task_base_v3.edge_paths){
        task_base.edge_paths.emplace_back(V3Msgs2TaskPath(path_v3));
    }
    task_base.pose = task_base_v3.pose;
    task_base.dynamic_adjust_path = task_base_v3.dynamic_adjust_path;
    task_base.utils_mode = task_base_v3.utils_mode;
    task_base.estimated_time = task_base_v3.estimated_time;
    task_base.estimated_distance = task_base_v3.estimated_distance;
    task_base.estimated_speed = task_base_v3.estimated_speed;
    task_base.estimated_efficiency = task_base_v3.estimated_efficiency;
    task_base.task_area = task_base_v3.task_area;
    task_base.path_gen = V3Msgs2PathGenerate(task_base_v3.path_gen);
    task_base.is_top = task_base_v3.is_top;
    task_base.is_assigned = task_base_v3.is_assigned;
    return task_base;
}


// TaskEcho -> v3_msgs::TaskEcho
v3_msgs::TaskEcho MsgConvert::TaskEcho2V3Msgs(TaskEcho task_echo){
    v3_msgs::TaskEcho task_echo_v3;
    task_echo_v3.task_name = task_echo.task_name;
    task_echo_v3.task_id = task_echo.task_id;
    task_echo_v3.add_time = task_echo.add_time;
    task_echo_v3.start_time = task_echo.start_time;
    task_echo_v3.end_time = task_echo.end_time;
    task_echo_v3.progress = task_echo.progress;
    task_echo_v3.working_time = task_echo.working_time;
    task_echo_v3.coverage_rate = task_echo.coverage_rate;
    task_echo_v3.cleaned_area = task_echo.cleaned_area;
    task_echo_v3.real_average_speed = task_echo.real_average_speed;
    task_echo_v3.real_travel_dist = task_echo.real_travel_dist;
    task_echo_v3.avoidance_obstacle_number = task_echo.avoidance_obstacle_number;
    task_echo_v3.extrication_number = task_echo.extrication_number;
    task_echo_v3.extrication_time = task_echo.extrication_time;
    task_echo_v3.missed_area = task_echo.missed_area;
    task_echo_v3.missed_number = task_echo.missed_number;
    task_echo_v3.missed_time = task_echo.missed_time;
    task_echo_v3.cleaned_path = TaskPath2V3Msgs(task_echo.cleaned_path);
    task_echo_v3.error_code = task_echo.error_code;
    task_echo_v3.task_status = TaskStatus2V3Msgs(task_echo.task_status);
    return task_echo_v3;
}

// v3_msgs::TaskEcho -> TaskEcho
TaskEcho MsgConvert::V3Msgs2TaskEcho(v3_msgs::TaskEcho task_echo_v3){
    TaskEcho task_echo;
    task_echo.task_name = task_echo_v3.task_name;
    task_echo.task_id = task_echo_v3.task_id;
    task_echo.add_time = task_echo_v3.add_time;
    task_echo.start_time = task_echo_v3.start_time;
    task_echo.end_time = task_echo_v3.end_time;
    task_echo.progress = task_echo_v3.progress;
    task_echo.working_time = task_echo_v3.working_time;
    task_echo.coverage_rate = task_echo_v3.coverage_rate;
    task_echo.cleaned_area = task_echo_v3.cleaned_area;
    task_echo.real_average_speed = task_echo_v3.real_average_speed;
    task_echo.real_travel_dist = task_echo_v3.real_travel_dist;
    task_echo.avoidance_obstacle_number = task_echo_v3.avoidance_obstacle_number;
    task_echo.extrication_number = task_echo_v3.extrication_number;
    task_echo.extrication_time = task_echo_v3.extrication_time;
    task_echo.missed_area = task_echo_v3.missed_area;
    task_echo.missed_number = task_echo_v3.missed_number;
    task_echo.missed_time = task_echo_v3.missed_time;
    task_echo.cleaned_path = V3Msgs2TaskPath(task_echo_v3.cleaned_path);
    task_echo.error_code = task_echo_v3.error_code;
    task_echo.task_status = V3Msgs2TaskStatus(task_echo_v3.task_status);
    return task_echo;
}

// TaskSingle -> v3_msgs::TaskSingle
v3_msgs::TaskSingle MsgConvert::TaskSingle2V3Msgs(TaskSingle task_single){
    v3_msgs::TaskSingle task_single_v3;
    task_single_v3.task_base = TaskBase2V3Msgs(task_single.task_base);
    task_single_v3.task_echo = TaskEcho2V3Msgs(task_single.task_echo);
    return task_single_v3;
}

// v3_msgs::TaskSingle -> TaskSingle
TaskSingle MsgConvert::V3Msgs2TaskSingle(v3_msgs::TaskSingle task_single_v3){
    TaskSingle task_single;
    task_single.task_base = V3Msgs2TaskBase(task_single_v3.task_base);
    task_single.task_echo = V3Msgs2TaskEcho(task_single_v3.task_echo);
    return task_single;
}

// TaskGroup -> v3_msgs::TaskGroup
v3_msgs::TaskGroup MsgConvert::TaskGroup2V3Msgs(TaskGroup task_group){
    v3_msgs::TaskGroup task_group_v3;
    task_group_v3.group_name = task_group.group_name;
    task_group_v3.group_id = task_group.group_id;
    task_group_v3.timertask_name = task_group.timertask_name;
    task_group_v3.timertask_id = task_group.timertask_id;
    for(auto& task_single : task_group.task_list){
        task_group_v3.task_list.emplace_back(TaskSingle2V3Msgs(task_single));
    }
    task_group_v3.is_top = task_group.is_top;
    return task_group_v3;
}

// v3_msgs::TaskGroup -> TaskGroup
TaskGroup MsgConvert::V3Msgs2TaskGroup(v3_msgs::TaskGroup task_group_v3){
    TaskGroup task_group;
    task_group.group_name = task_group_v3.group_name;
    task_group.group_id = task_group_v3.group_id;
    task_group.timertask_name = task_group_v3.timertask_name;
    task_group.timertask_id = task_group_v3.timertask_id;
    for(auto& task_single : task_group_v3.task_list){
        task_group.task_list.emplace_back(V3Msgs2TaskSingle(task_single));
    }
    task_group.is_top = task_group_v3.is_top;
    return task_group;
}

// TimerTask -> v3_msgs::TimerTask
v3_msgs::TimerTask MsgConvert::TimerTask2V3Msgs(TimerTask timer_task){
    v3_msgs::TimerTask timer_task_v3;
    timer_task_v3.timertask_name = timer_task.timertask_name;
    timer_task_v3.timertask_id = timer_task.timertask_id;
    timer_task_v3.enable = timer_task.enable;
    timer_task_v3.start_time = timer_task.start_time;
    timer_task_v3.forced_end_time = timer_task.forced_end_time;
    timer_task_v3.timetable = timer_task.timetable;
    timer_task_v3.forced_end_time_enable = timer_task.forced_end_time_enable;
    for(auto& task_group : timer_task.taskgroup_list){
        timer_task_v3.taskgroup_list.emplace_back(TaskGroup2V3Msgs(task_group));
    }
    timer_task_v3.estimated_time = timer_task.estimated_time;
    timer_task_v3.is_top = timer_task.is_top;
    timer_task_v3.multi_maps_shared = timer_task.multi_maps_shared;
    timer_task_v3.map_name = timer_task.map_name;
    return timer_task_v3;
}

// v3_msgs::TimerTask -> TimerTask
TimerTask MsgConvert::V3Msgs2TimerTask(v3_msgs::TimerTask timer_task_v3){
    TimerTask timer_task;
    timer_task.timertask_name = timer_task_v3.timertask_name;
    timer_task.timertask_id = timer_task_v3.timertask_id;
    timer_task.enable = timer_task_v3.enable;
    timer_task.start_time = timer_task_v3.start_time;
    timer_task.forced_end_time = timer_task_v3.forced_end_time;
    timer_task.timetable = timer_task_v3.timetable;
    timer_task.forced_end_time_enable = timer_task_v3.forced_end_time_enable;
    for(auto& task_group : timer_task_v3.taskgroup_list){
        timer_task.taskgroup_list.emplace_back(V3Msgs2TaskGroup(task_group));
    }
    timer_task.estimated_time = timer_task_v3.estimated_time;
    timer_task.is_top = timer_task_v3.is_top;
    timer_task.multi_maps_shared = timer_task_v3.multi_maps_shared;
    timer_task.map_name = timer_task_v3.map_name;
    return timer_task;
}

// OnlineTask -> v3_msgs::OnlineTask
v3_msgs::OnlineTask MsgConvert::OnlineTask2V3Msgs(OnlineTask online_task){
    v3_msgs::OnlineTask online_task_v3;
    for(auto& task_group : online_task.taskgroup_list){
        online_task_v3.taskgroup_list.emplace_back(TaskGroup2V3Msgs(task_group));
    }
    return online_task_v3;
}

// v3_msgs::OnlineTask -> OnlineTask
OnlineTask MsgConvert::V3Msgs2OnlineTask(v3_msgs::OnlineTask online_task_v3){
    OnlineTask online_task;
    for(auto& task_group : online_task_v3.taskgroup_list){
        online_task.taskgroup_list.emplace_back(V3Msgs2TaskGroup(task_group));
    }
    return online_task;
}

// TaskPicture -> v3_msgs::TaskPicture
v3_msgs::TaskPicture MsgConvert::TaskPicture2V3Msgs(TaskPicture task_picture){
    v3_msgs::TaskPicture task_picture_v3;
    task_picture_v3.png_file_path = task_picture.png_file_path;
    task_picture_v3.png_str = task_picture.png_str;
    task_picture_v3.qiniu_file_key = task_picture.qiniu_file_key;
    task_picture_v3.map_name = task_picture.map_name;
    return task_picture_v3;
}

// v3_msgs::TaskPicture -> TaskPicture
TaskPicture MsgConvert::V3Msgs2TaskPicture(v3_msgs::TaskPicture task_picture_v3){
    TaskPicture task_picture;
    task_picture.png_file_path = task_picture_v3.png_file_path;
    task_picture.png_str = task_picture_v3.png_str;
    task_picture.qiniu_file_key = task_picture_v3.qiniu_file_key;
    task_picture.map_name = task_picture_v3.map_name;
    return task_picture;
}

// TaskRecord -> v3_msgs::TaskRecord
v3_msgs::TaskRecord MsgConvert::TaskRecord2V3Msgs(TaskRecord task_record){
    v3_msgs::TaskRecord task_record_v3;
    task_record_v3.task_group = TaskGroup2V3Msgs(task_record.task_group);
    task_record_v3.start_time = task_record.start_time;
    task_record_v3.end_time = task_record.end_time;
    task_record_v3.working_time = task_record.working_time;
    task_record_v3.total_area = task_record.total_area;
    task_record_v3.cleaned_area = task_record.cleaned_area;
    task_record_v3.uncleaned_area = task_record.uncleaned_area;
    task_record_v3.cleaning_efficiency = task_record.cleaning_efficiency;
    task_record_v3.coverage_rate = task_record.coverage_rate;
    task_record_v3.error_code = task_record.error_code;
    for(auto& task_picture : task_record.task_pictures){
        task_record_v3.task_pictures.emplace_back(TaskPicture2V3Msgs(task_picture));
    }
    task_record_v3.status = TaskStatus2V3Msgs(task_record.status);
    return task_record_v3;
}

// v3_msgs::TaskRecord -> TaskRecord
TaskRecord MsgConvert::V3Msgs2TaskRecord(v3_msgs::TaskRecord task_record_v3){
    TaskRecord task_record;
    task_record.task_group = V3Msgs2TaskGroup(task_record_v3.task_group);
    task_record.start_time = task_record_v3.start_time;
    task_record.end_time = task_record_v3.end_time;
    task_record.working_time = task_record_v3.working_time;
    task_record.total_area = task_record_v3.total_area;
    task_record.cleaned_area = task_record_v3.cleaned_area;
    task_record.uncleaned_area = task_record_v3.uncleaned_area;
    task_record.cleaning_efficiency = task_record_v3.cleaning_efficiency;
    task_record.coverage_rate = task_record_v3.coverage_rate;
    task_record.error_code = task_record_v3.error_code;
    for(auto& task_picture : task_record_v3.task_pictures){
        task_record.task_pictures.emplace_back(V3Msgs2TaskPicture(task_picture));
    }
    task_record.status = V3Msgs2TaskStatus(task_record_v3.status);
    return task_record;
}

// v3_msgs::PathGenerate -> PathGenerate
PathGenerate MsgConvert::V3Msgs2PathGenerate(v3_msgs::PathGenerate& path_gen_msg){
    PathGenerate path_gen;
    for(auto& path_type : path_gen_msg.path_types){
        path_gen.path_types.emplace_back(V3Msgs2PathGenerateType(path_type));
    }
    for(auto& path_type : path_gen_msg.path_types_child){
        path_gen.path_types_child.emplace_back(V3Msgs2PathGenerateType(path_type));
    }
    // path_gen.path_type = V3Msgs2PathGenerateType(path_gen_msg.path_type);
    // path_gen.path_type_child = V3Msgs2PathGenerateType(path_gen_msg.path_type_child);
    path_gen.path_action = V3Msgs2PathGenerateAction(path_gen_msg.path_action);
    path_gen.using_map = path_gen_msg.using_map;
    path_gen.offset = path_gen_msg.offset;
    // path_gen.cancel_polygon_inflation = path_gen_msg.cancel_polygon_inflation;
    path_gen.danger_areas = path_gen_msg.danger_areas;
    return path_gen;
}

// PathGenerate -> v3_msgs::PathGenerate
v3_msgs::PathGenerate MsgConvert::PathGenerate2V3Msgs(const PathGenerate& path_gen){
    v3_msgs::PathGenerate path_gen_msg;
    for(auto& path_type : path_gen.path_types){
        path_gen_msg.path_types.emplace_back(PathGenerateType2V3Msgs(path_type));
    }
    for(auto& path_type : path_gen.path_types_child){
        path_gen_msg.path_types_child.emplace_back(PathGenerateType2V3Msgs(path_type));
    }
    // path_gen_msg.path_type = PathGenerateType2V3Msgs(path_gen.path_type);
    // path_gen_msg.path_type_child = PathGenerateType2V3Msgs(path_gen.path_type_child);
    path_gen_msg.path_action = PathGenerateAction2V3Msgs(path_gen.path_action);
    path_gen_msg.using_map = path_gen.using_map;
    path_gen_msg.offset = path_gen.offset;
    // path_gen_msg.cancel_polygon_inflation = path_gen.cancel_polygon_inflation;
    path_gen_msg.danger_areas = path_gen.danger_areas;
    return path_gen_msg;
}


/*******************************************
* 转换成字符串
*******************************************/
// TaskType -> string
string MsgConvert::TaskType2Str(TaskType task_type){
    switch(task_type){
        case TaskType::CHARGING_TASK: 
            return "CHARGING_TASK";
        case TaskType::P2P_TASK: 
            return "P2P_TASK";
        case TaskType::TEACH_TASK: 
            return "TEACH_TASK";
        case TaskType::SWEEP_TASK: 
            return "SWEEP_TASK";
        case TaskType::ELEVATOR_TRANS_TASK: 
            return "ELEVATOR_TRANS_TASK";
        case TaskType::UNKNOWN: 
            return "UNKNOWN";
        default: 
            return "UNKNOWN";
    }
}

// string -> TaskType
TaskType MsgConvert::Str2TaskType(string task_type){
    if(task_type == "CHARGING_TASK") 
        return TaskType::CHARGING_TASK;
    else if(task_type == "P2P_TASK") 
        return TaskType::P2P_TASK;
    else if(task_type == "TEACH_TASK") 
        return TaskType::TEACH_TASK;
    else if(task_type == "SWEEP_TASK") 
        return TaskType::SWEEP_TASK;
    else if(task_type == "ELEVATOR_TRANS_TASK") 
        return TaskType::ELEVATOR_TRANS_TASK;
    else if(task_type == "UNKNOWN") 
        return TaskType::UNKNOWN;
    else 
        return TaskType::UNKNOWN;
}

// TaskState -> string
string MsgConvert::TaskState2Str(TaskState task_state){
    switch(task_state){
        case TaskState::UNKNOWN: 
            return "UNKNOWN";
        case TaskState::IDLE: 
            return "IDLE";
        case TaskState::EXECUING: 
            return "EXECUING";
        case TaskState::PAUSE: 
            return "PAUSE";
        case TaskState::BLOCKED: 
            return "BLOCKED";
        case TaskState::FINISHED: 
            return "FINISHED";
        case TaskState::USER_CANCEL: 
            return "USER_CANCEL";
        case TaskState::TERMINATED: 
            return "TERMINATED";
        case TaskState::ERROR: 
            return "ERROR";
        default: 
            return "UNKNOWN";
    }
}

// string -> TaskState
TaskState MsgConvert::Str2TaskState(string task_state){
    if(task_state == "UNKNOWN") 
        return TaskState::UNKNOWN;
    else if(task_state == "IDLE") 
        return TaskState::IDLE;
    else if(task_state == "EXECUING") 
        return TaskState::EXECUING;
    else if(task_state == "PAUSE") 
        return TaskState::PAUSE;
    else if(task_state == "BLOCKED") 
        return TaskState::BLOCKED;
    else if(task_state == "FINISHED") 
        return TaskState::FINISHED;
    else if(task_state == "USER_CANCEL") 
        return TaskState::USER_CANCEL;
    else if(task_state == "TERMINATED") 
        return TaskState::TERMINATED;
    else if(task_state == "ERROR") 
        return TaskState::ERROR;
    else 
        return TaskState::UNKNOWN;
}


// EdgeMode -> string
string MsgConvert::EdgeMode2Str(EdgeMode edge_mode){
    switch(edge_mode){
        case EdgeMode::UNKNOWN: 
            return "UNKNOWN";
        case EdgeMode::EDGE_ZERO_MODE: 
            return "EDGE_ZERO_MODE";
        case EdgeMode::EDGE_5CM_MODE: 
            return "EDGE_5CM_MODE";
        default: 
            return "UNKNOWN";    
    }
}

// string -> EdgeMode
EdgeMode MsgConvert::Str2EdgeMode(string edge_mode){
    if(edge_mode == "UNKNOWN") 
        return EdgeMode::UNKNOWN;
    else if(edge_mode == "EDGE_ZERO_MODE") 
        return EdgeMode::EDGE_ZERO_MODE;
    else if(edge_mode == "EDGE_5CM_MODE") 
        return EdgeMode::EDGE_5CM_MODE;
    else 
        return EdgeMode::UNKNOWN;
}

// TaskControlMode -> string
string MsgConvert::TaskControlMode2Str(TaskControlMode task_control_mode){
    switch(task_control_mode){
        case TaskControlMode::SWEEP_STANDARD_MODE: 
            return "SWEEP_STANDARD_MODE";
        case TaskControlMode::SWEEP_EDGE_MODE: 
            return "SWEEP_EDGE_MODE";
        case TaskControlMode::SWEEP_STANDARD_AND_EDGE: 
            return "SWEEP_STANDARD_AND_EDGE";
        case TaskControlMode::FOLLOW_MODE: 
            return "FOLLOW_MODE";
        case TaskControlMode::UNKNOWN: 
            return "UNKNOWN";
        // case TaskControlMode::P2P_MODE: 
        //     return "P2P_MODE";
        // case TaskControlMode::CHARGING_MODE: 
        //     return "CHARGING_MODE";
        // case TaskControlMode::ELEVATOR_TRANS_MODE: 
        //     return "ELEVATOR_TRANS_MODE";
        default: 
            return "UNKNOWN";
    }
}

// string -> TaskControlMode
TaskControlMode MsgConvert::Str2TaskControlMode(string task_control_mode){
    if(task_control_mode == "SWEEP_STANDARD_MODE") 
        return TaskControlMode::SWEEP_STANDARD_MODE;
    else if(task_control_mode == "SWEEP_EDGE_MODE") 
        return TaskControlMode::SWEEP_EDGE_MODE;
    else if(task_control_mode == "SWEEP_STANDARD_AND_EDGE") 
        return TaskControlMode::SWEEP_STANDARD_AND_EDGE;
    else if(task_control_mode == "FOLLOW_MODE") 
        return TaskControlMode::FOLLOW_MODE;
    else if(task_control_mode == "UNKNOWN") 
        return TaskControlMode::UNKNOWN;
    // else if(task_control_mode == "P2P_MODE") 
    //     return TaskControlMode::P2P_MODE;
    // else if(task_control_mode == "CHARGING_MODE") 
    //     return TaskControlMode::CHARGING_MODE;
    // else if(task_control_mode == "ELEVATOR_TRANS_MODE") 
    //     return TaskControlMode::ELEVATOR_TRANS_MODE;
    else 
        return TaskControlMode::UNKNOWN;
}

// TaskSpeed -> string
string MsgConvert::TaskSpeed2Str(TaskSpeed task_speed){
    switch(task_speed){
        case TaskSpeed::LOW_SPEED:
            return "LOW_SPEED";
        case TaskSpeed::MIDDLE_SPEED:
            return "MIDDLE_SPEED";
        case TaskSpeed::HIGH_SPEED:
            return "HIGH_SPEED";
        default:
            return "LOW_SPEED";
    }
}

// string -> TaskSpeed
TaskSpeed MsgConvert::Str2TaskSpeed(string task_speed){
    if(task_speed == "LOW_SPEED") 
        return TaskSpeed::LOW_SPEED;
    else if(task_speed == "MIDDLE_SPEED") 
        return TaskSpeed::MIDDLE_SPEED;
    else if(task_speed == "HIGH_SPEED") 
        return TaskSpeed::HIGH_SPEED;
    else 
        return TaskSpeed::LOW_SPEED;
}

// PathGenerateType -> string
string MsgConvert::PathGenerateType2Str(PathGenerateType path_generate_type){
    switch(path_generate_type){
        case PathGenerateType::BOUSTROPHEDON_METHOD: 
            return "BOUSTROPHEDON_METHOD";
        case PathGenerateType::ARC_BOUSTROPHEDON_METHOD: 
            return "ARC_BOUSTROPHEDON_METHOD";
        case PathGenerateType::WRAPPER_METHOD: 
            return "WRAPPER_METHOD";
        case PathGenerateType::EDGE_METHOD: 
            return "EDGE_METHOD";
        case PathGenerateType::P2P_METHOD: 
            return "P2P_METHOD";
        case PathGenerateType::MANUAL_METHOD: 
            return "MANUAL_METHOD";
        case PathGenerateType::MANUAL_POLYGON_METHOD: 
            return "MANUAL_POLYGON_METHOD";
        case PathGenerateType::AUTO_METHOD: 
            return "AUTO_METHOD";
        case PathGenerateType::UNKNOWN: 
            return "UNKNOWN";
        default: 
            return "UNKNOWN";
    }
}

// string -> PathGenerateType
PathGenerateType MsgConvert::Str2PathGenerateType(string path_generate_type){
    if(path_generate_type == "BOUSTROPHEDON_METHOD") 
        return PathGenerateType::BOUSTROPHEDON_METHOD;
    else if(path_generate_type == "ARC_BOUSTROPHEDON_METHOD") 
        return PathGenerateType::ARC_BOUSTROPHEDON_METHOD;
    else if(path_generate_type == "WRAPPER_METHOD") 
        return PathGenerateType::WRAPPER_METHOD;
    else if(path_generate_type == "EDGE_METHOD")
        return PathGenerateType::EDGE_METHOD;
    else if(path_generate_type == "P2P_METHOD") 
        return PathGenerateType::P2P_METHOD;
    else if(path_generate_type == "MANUAL_METHOD") 
        return PathGenerateType::MANUAL_METHOD;
    else if(path_generate_type == "MANUAL_POLYGON_METHOD") 
        return PathGenerateType::MANUAL_POLYGON_METHOD;
    else if(path_generate_type == "AUTO_METHOD") 
        return PathGenerateType::AUTO_METHOD;
    else if(path_generate_type == "UNKNOWN") 
        return PathGenerateType::UNKNOWN;
}

// PathGenerateAction -> string
string MsgConvert::PathGenerateAction2Str(PathGenerateAction path_generate_action){
    switch(path_generate_action){
        case PathGenerateAction::UNKNOWN: 
            return "UNKNOWN";
        case PathGenerateAction::START_RECORD: 
            return "START_RECORD";
        case PathGenerateAction::FINISHED_RECORD: 
            return "FINISHED_RECORD";
        case PathGenerateAction::CANCEL_RECORD: 
            return "CANCEL_RECORD";
        default: 
            return "UNKNOWN";
    }
}

// string -> PathGenerateAction
PathGenerateAction MsgConvert::Str2PathGenerateAction(string path_generate_action){
    if(path_generate_action == "UNKNOWN") 
        return PathGenerateAction::UNKNOWN;
    else if(path_generate_action == "START_RECORD") 
        return PathGenerateAction::START_RECORD;
    else if(path_generate_action == "FINISHED_RECORD") 
        return PathGenerateAction::FINISHED_RECORD;
    else if(path_generate_action == "CANCEL_RECORD") 
        return PathGenerateAction::CANCEL_RECORD;
}

// DeviceType -> string
string MsgConvert::DeviceType2Str(DeviceType device_type){
    switch(device_type){
        case DeviceType::SWEEP_DEVICE: 
            return "SWEEP_DEVICE";
        case DeviceType::WASH_DEVICE: 
            return "WASH_DEVICE";
        default: 
            return "SWEEP_DEVICE";
    }
}

// string -> DeviceType
DeviceType MsgConvert::Str2DeviceType(string device_type){
    if(device_type == "SWEEP_DEVICE") 
        return DeviceType::SWEEP_DEVICE;
    else if(device_type == "WASH_DEVICE") 
        return DeviceType::WASH_DEVICE;
}

// 定时任务转字符串 TimerTask -> string
string MsgConvert::TimerTask2Str(TimerTask timer_task){
    string msg;
    msg += "timertask_name: ";
    msg += timer_task.timertask_name;
    msg += ", enable: ";
    msg += Bool2Str(timer_task.enable);
    msg += ", start_time: ";
    msg += timer_task.start_time;
    msg += ", timetable: ";
    for(auto& item : timer_task.timetable){
        msg += to_string(item);
    }
    msg += ", forced_end_time: ";
    msg += timer_task.forced_end_time;
    msg += ", forced_end_time_enable: ";
    msg += Bool2Str(timer_task.forced_end_time_enable);
    msg += ", is_top: ";
    msg += Bool2Str(timer_task.is_top);
    msg += ", multi_maps_shared: ";
    msg += Bool2Str(timer_task.multi_maps_shared);
    msg += ", map_name: ";
    msg += timer_task.map_name;
    return msg;    
}

/*******************************************
 * JSON 消息数据转换
 *******************************************/
// v3_msgs::Building -> Json::Value
Json::Value MsgConvert::Building2Json(v3_msgs::Building& building){
    Json::Value json_data;
    json_data["name"] = building.name;
    return json_data;
}

// Json::Value -> v3_msgs::Building
v3_msgs::Building MsgConvert::Json2Building(Json::Value& json_data){
    v3_msgs::Building building;
    if(CheckJsonItemIsValid(json_data, "name"))
        building.name = json_data["name"].asString();
    return building;
}

// v3_msgs::Floor -> Json::Value
Json::Value MsgConvert::Floor2Json(v3_msgs::Floor& floor){
    Json::Value json_data;
    json_data["floor"] = floor.floor;
    json_data["shared"] = Bool2Str(floor.shared);
    Json::Value json_buildings;
    for(auto building : floor.shared_buildings){
        json_buildings.append(Building2Json(building));
    }
    json_data["shared_buildings"] = json_buildings;
    return json_data;
}

// Json::Value -> v3_msgs::Floor
v3_msgs::Floor MsgConvert::Json2Floor(Json::Value& json_data){
    v3_msgs::Floor floor;
    if(CheckJsonItemIsValid(json_data, "floor"))
        floor.floor = json_data["floor"].asInt();
    if(CheckJsonItemIsValid(json_data, "shared"))
        floor.shared = Str2Bool(json_data["shared"].asString());
    if(CheckJsonItemIsValid(json_data, "shared_buildings")){
        for(auto json_building : json_data["shared_buildings"]){
            floor.shared_buildings.emplace_back(Json2Building(json_building));
        }
    }
    return floor;
}

// v3_msgs::MapBase -> Json
Json::Value MsgConvert::MapBase2Json(v3_msgs::MapBase& map_base){
    Json::Value json_data;
    json_data["building"] = Building2Json(map_base.building);
    json_data["floor"] = Floor2Json(map_base.floor);
    json_data["name"] = map_base.name;
    json_data["id"] = map_base.id;
    json_data["metadata"] = MapMetaData2Json(map_base.metadata);
    json_data["create_time"] = map_base.create_time;
    json_data["is_top"] = Bool2Str(map_base.is_top);
    json_data["area"] = map_base.area;
    json_data["rotate_angle"] = map_base.rotate_angle;
    json_data["slam_software_version"] = map_base.slam_software_version; 
    json_data["slam_image_version"] = map_base.slam_image_version; 
    return json_data;
}

// Json::Value -> v3_msgs::MapBase
v3_msgs::MapBase MsgConvert::Json2MapBase(Json::Value& json_data){
    v3_msgs::MapBase map_base;
    if(CheckJsonItemIsValid(json_data, "name"))
        map_base.name = json_data["name"].asString();
    if(CheckJsonItemIsValid(json_data, "id"))
        map_base.id = json_data["id"].asString();
    if(CheckJsonItemIsValid(json_data, "building")){
        map_base.building = Json2Building(json_data["building"]);
    }
    if(CheckJsonItemIsValid(json_data, "floor")){
        map_base.floor = Json2Floor(json_data["floor"]);
    }
    if(CheckJsonItemIsValid(json_data, "metadata")){
        map_base.metadata = Json2MapMetaData(json_data["metadata"]);
    }
    if(CheckJsonItemIsValid(json_data, "create_time"))
        map_base.create_time = json_data["create_time"].asString();
    if(CheckJsonItemIsValid(json_data, "is_top"))
        map_base.is_top = Str2Bool(json_data["is_top"].asString());
    if(CheckJsonItemIsValid(json_data, "area"))
        map_base.area = stof(json_data["area"].asString());
    if(CheckJsonItemIsValid(json_data, "rotate_angle"))
        map_base.rotate_angle = stof(json_data["rotate_angle"].asString());
    if(CheckJsonItemIsValid(json_data, "slam_software_version"))
        map_base.slam_software_version = json_data["slam_software_version"].asString();  
    if(CheckJsonItemIsValid(json_data, "slam_image_version"))
        map_base.slam_image_version = json_data["slam_image_version"].asString();  
    return map_base;
}


// // TaskType -> Json::Value
// Json::Value MsgConvert::TaskType2Json(TaskType task_type){
//     Json::Value json_data;
//     json_data["task_type"] = TaskType2Str(task_type);
//     return json_data;
// }

// Json::Value -> TaskType
TaskType MsgConvert::Json2TaskType(Json::Value& json_data){
    TaskType task_type;
    if(CheckJsonItemIsValid(json_data, "task_type")){
        std::string str = json_data["task_type"].asString();
        task_type = Str2TaskType(str);
    }
    return task_type;
}

// // DeviceType -> Json::Value
// Json::Value MsgConvert::DeviceType2Json(DeviceType device_type){
//     Json::Value json_data;
//     json_data["device_type"] = DeviceType2Str(device_type);
//     return json_data;
// }

// Json::Value -> DeviceType
DeviceType MsgConvert::Json2DeviceType(Json::Value& json_data){
    DeviceType device_type;
    if(CheckJsonItemIsValid(json_data, "device_type")){
        std::string str = json_data["device_type"].asString();
        device_type = Str2DeviceType(str);
    }
    return device_type;
}

// // TaskControlMode -> Json::Value
// Json::Value MsgConvert::TaskControlMode2Json(TaskControlMode task_control_mode){
//     Json::Value json_data;
//     json_data["task_control_mode"] = TaskControlMode2Str(task_control_mode);
//     return json_data;
// }

// Json::Value -> TaskControlMode
TaskControlMode MsgConvert::Json2TaskControlMode(Json::Value& json_data){
    TaskControlMode task_control_mode;
    if(CheckJsonItemIsValid(json_data, "task_control_mode")){
        std::string str = json_data["task_control_mode"].asString();
        task_control_mode = Str2TaskControlMode(str);
    }
    return task_control_mode;
}

// // EdgeMode -> Json::Value
// Json::Value MsgConvert::EdgeMode2Json(EdgeMode edge_mode){
//     Json::Value json_data;
//     json_data["edge_mode"] = EdgeMode2Str(edge_mode);
//     return json_data;
// }

// Json::Value -> EdgeMode
EdgeMode MsgConvert::Json2EdgeMode(Json::Value& json_data){
    EdgeMode edge_mode;
    if(CheckJsonItemIsValid(json_data, "edge_mode")){
        std::string str = json_data["edge_mode"].asString();
        edge_mode = Str2EdgeMode(str);
    }
    return edge_mode;
}

// // TaskSpeed -> Json::Value
// Json::Value MsgConvert::TaskSpeed2Json(TaskSpeed task_speed){
//     Json::Value json_data;
//     json_data["task_speed"] = TaskSpeed2Str(task_speed);
//     return json_data;
// }

// Json::Value -> TaskSpeed
TaskSpeed MsgConvert::Json2TaskSpeed(Json::Value& json_data){
    TaskSpeed task_speed;
    if(CheckJsonItemIsValid(json_data, "task_speed")){
        std::string str = json_data["task_speed"].asString();
        task_speed = Str2TaskSpeed(str);
    }
    return task_speed;
}

// TaskPath -> Json::Value
Json::Value MsgConvert::TaskPath2Json(TaskPath& task_path){
    Json::Value json_data;
    json_data["path_type"] = PathGenerateType2Str(task_path.path_type);
    json_data["poses"] = Poses2Json(task_path.poses);
    json_data["path_interval"] = task_path.path_interval;
    return json_data;
}

// Json::Value -> TaskPath
TaskPath MsgConvert::Json2TaskPath(Json::Value& json_data){
    TaskPath task_path;
    if(CheckJsonItemIsValid(json_data, "path_type")){
        task_path.path_type = Str2PathGenerateType(json_data["path_type"].asString());
    }
    if(CheckJsonItemIsValid(json_data, "poses")){
        task_path.poses = Json2Poses(json_data["poses"]);
    }
    if(CheckJsonItemIsValid(json_data, "path_interval")){
        task_path.path_interval = json_data["path_interval"].asFloat();
    }
    return task_path;
}

// v3_msgs::PolygonData -> Json::Value
Json::Value MsgConvert::PolygonData2Json(v3_msgs::PolygonData& polygon){
    Json::Value json_data;
    json_data["poses"] = Poses2Json(polygon.poses);
    return json_data;
}

// Json::Value -> v3_msgs::PolygonData
v3_msgs::PolygonData MsgConvert::Json2PolygonData(Json::Value& json_data){
    v3_msgs::PolygonData polygon;
    if(CheckJsonItemIsValid(json_data, "poses")){
        polygon.poses = Json2Poses(json_data["poses"]);
    }
    return polygon;
}

//  PathGenerate -> Json::Value
Json::Value MsgConvert::PathGenerate2Json(PathGenerate& path_generate){
    Json::Value json_data;
    Json::Value path_types_json;
    for(auto& path_type : path_generate.path_types){
        path_types_json.append(PathGenerateType2Str(path_type));
    }
    json_data["path_types"] = path_types_json;
    Json::Value path_types_child_json;
    for(auto& path_type : path_generate.path_types_child){
        path_types_child_json.append(PathGenerateType2Str(path_type));
    }
    json_data["path_types_child"] = path_types_child_json;   
    // json_data["path_type"] = PathGenerateType2Str(path_generate.path_type);
    // json_data["path_type_child"] = PathGenerateType2Str(path_generate.path_type_child);
    json_data["path_action"] = PathGenerateAction2Str(path_generate.path_action);
    json_data["using_map"] = Bool2Str(path_generate.using_map);
    json_data["offset"] = path_generate.offset;
    // json_data["cancel_polygon_inflation"] = Bool2Str(path_generate.cancel_polygon_inflation);
    Json::Value danger_areas_json;
    for(auto&polygon : path_generate.danger_areas){
        danger_areas_json.append(PolygonData2Json(polygon));
    }
    json_data["danger_areas"] = danger_areas_json;
    return json_data;
}

// Json::Value -> PathGenerate
PathGenerate MsgConvert::Json2PathGenerate(Json::Value& json_data){
    PathGenerate path_generate;
    // if(CheckJsonItemIsValid(json_data, "path_type")){
    //     path_generate.path_type = Str2PathGenerateType(json_data["path_type"].asString());
    // }
    // if(CheckJsonItemIsValid(json_data, "path_type_child")){
    //     path_generate.path_type_child = Str2PathGenerateType(json_data["path_type_child"].asString());
    // }
    if(CheckJsonItemIsValid(json_data, "path_types")){
        for(auto& path_type : json_data["path_types"]){
            path_generate.path_types.push_back(Str2PathGenerateType(path_type.asString()));
        }
    }
    if(CheckJsonItemIsValid(json_data, "path_types_child")){
        for(auto& path_type : json_data["path_types_child"]){
            path_generate.path_types_child.push_back(Str2PathGenerateType(path_type.asString()));
        }
    }
    if(CheckJsonItemIsValid(json_data, "path_action")){
        path_generate.path_action = Str2PathGenerateAction(json_data["path_action"].asString());
    }
    if(CheckJsonItemIsValid(json_data, "using_map")){
        path_generate.using_map = Str2Bool(json_data["using_map"].asString());
    }
    if(CheckJsonItemIsValid(json_data, "offset")){
        path_generate.offset = json_data["offset"].asFloat();
    }
    // if(CheckJsonItemIsValid(json_data, "cancel_polygon_inflation")){
    //     path_generate.cancel_polygon_inflation = Str2Bool(json_data["cancel_polygon_inflation"].asString());
    // }
    if(CheckJsonItemIsValid(json_data, "danger_areas")){
        for(auto& polygon : json_data["danger_areas"]){
            path_generate.danger_areas.push_back(Json2PolygonData(polygon));
        }
    }
    return path_generate;
}


// TaskBase -> Json::Value
Json::Value MsgConvert::TaskBase2Json(TaskBase& task_base){
    Json::Value json_data;
    json_data["task_name"] = task_base.task_name;
    json_data["task_id"] = task_base.task_id;
    json_data["map_name"] = task_base.map_base.name;
    json_data["map_base"] = MapBase2Json(task_base.map_base);
    json_data["next_map_base"] = MapBase2Json(task_base.next_map_base);
    json_data["group_name"] = task_base.group_name;
    json_data["group_id"] = task_base.group_id;
    json_data["task_type"] = TaskType2Str(task_base.task_type);
    json_data["start"] = Pose2Json(task_base.start);
    json_data["polygon"] = PolygonData2Json(task_base.polygon);
    json_data["device_type"] = DeviceType2Str(task_base.device_type);
    json_data["control_mode"] = TaskControlMode2Str(task_base.control_mode);
    json_data["edge_mode"] = EdgeMode2Str(task_base.edge_mode);
    json_data["task_speed"] = TaskSpeed2Str(task_base.task_speed);
    Json::Value paths_json;
    for(auto& task_path : task_base.paths){
        paths_json.append(TaskPath2Json(task_path));
    }
    json_data["paths"] = paths_json;
    Json::Value edge_paths_json;
    for(auto& task_path : task_base.edge_paths){
        edge_paths_json.append(TaskPath2Json(task_path));
    }
    json_data["pose"] = Pose2Json(task_base.pose);
    json_data["edge_paths"] = edge_paths_json;
    json_data["dynamic_adjust_path"] = Bool2Str(task_base.dynamic_adjust_path);
    json_data["utils_mode"] = task_base.utils_mode;
    json_data["estimated_time"] = task_base.estimated_time;
    json_data["estimated_distance"] = task_base.estimated_distance;
    json_data["estimated_speed"] = task_base.estimated_speed;
    json_data["estimated_efficiency"] = task_base.estimated_efficiency;
    json_data["task_area"] = task_base.task_area;
    json_data["path_gen"] = PathGenerate2Json(task_base.path_gen);
    json_data["is_top"] = Bool2Str(task_base.is_top);
    json_data["is_assigned"] = Bool2Str(task_base.is_assigned);
    return json_data;
}

// Json::Value -> TaskBase
TaskBase MsgConvert::Json2TaskBase(Json::Value& json_data){
    TaskBase task_base;
    if(CheckJsonItemIsValid(json_data, "task_name")){
        task_base.task_name = json_data["task_name"].asString();
    }
    if(CheckJsonItemIsValid(json_data, "task_id")){
        task_base.task_id = json_data["task_id"].asString();
    }
    if(CheckJsonItemIsValid(json_data, "map_base")){
        if(json_data["map_base"].isObject()){
            task_base.map_base = Json2MapBase(json_data["map_base"]);
        }
        else{
            Json::Value parser_data = String2JsonValue(json_data["map_base"].asString());
            task_base.map_base = Json2MapBase(parser_data);
        }
    }
    if(CheckJsonItemIsValid(json_data, "next_map_base")){
        if(json_data["next_map_base"].isObject()){
            task_base.next_map_base = Json2MapBase(json_data["next_map_base"]);
        }
        else{
            Json::Value parser_data = String2JsonValue(json_data["next_map_base"].asString());
            task_base.next_map_base = Json2MapBase(parser_data);
        }
    }
    // cout << "[Json2TaskBase] next_map_base" << endl;
    if(CheckJsonItemIsValid(json_data, "group_name")){
        task_base.group_name = json_data["group_name"].asString();
    }
    if(CheckJsonItemIsValid(json_data, "group_id")){
        task_base.group_id = json_data["group_id"].asString();
    }
    if(CheckJsonItemIsValid(json_data, "task_type")){
        task_base.task_type = Str2TaskType(json_data["task_type"].asString());
    }
    if(CheckJsonItemIsValid(json_data, "start")){
        if(json_data["start"].isObject()){
            task_base.start = Json2Pose(json_data["start"]);
        }
        else{
            Json::Value parser_data = String2JsonValue(json_data["start"].asString());
            task_base.start = Json2Pose(parser_data);
        }
    }
    // cout << "[Json2TaskBase] start" << endl;
    if(CheckJsonItemIsValid(json_data, "polygon")){
        if(json_data["polygon"].isObject()){
            task_base.polygon = Json2PolygonData(json_data["polygon"]);
        }
        else{
            Json::Value parser_data = String2JsonValue(json_data["polygon"].asString());
            task_base.polygon = Json2PolygonData(parser_data);
        }
    }
    if(CheckJsonItemIsValid(json_data, "device_type")){
        task_base.device_type = Str2DeviceType(json_data["device_type"].asString());
    }
    if(CheckJsonItemIsValid(json_data, "control_mode")){
        task_base.control_mode = Str2TaskControlMode(json_data["control_mode"].asString());
    }
    if(CheckJsonItemIsValid(json_data, "edge_mode")){
        task_base.edge_mode = Str2EdgeMode(json_data["edge_mode"].asString());
    }
    if(CheckJsonItemIsValid(json_data, "task_speed")){
        task_base.task_speed = Str2TaskSpeed(json_data["task_speed"].asString());
    }
    // cout << "[Json2TaskBase] task_speed" << endl;
    if(CheckJsonItemIsValid(json_data, "paths")){
        if(json_data["paths"].isArray()){
            for(auto& path_json : json_data["paths"]){
                task_base.paths.push_back(Json2TaskPath(path_json));
            }
        }
        else{
            Json::Value parser_data = String2JsonValue(json_data["paths"].asString());
            for(auto& path_json : parser_data){
                task_base.paths.push_back(Json2TaskPath(path_json));
            }
        }
    }
    // cout << "[Json2TaskBase] paths" << endl;
    if(CheckJsonItemIsValid(json_data, "edge_paths")){
        if(json_data["edge_paths"].isArray()){
            for(auto& path_json : json_data["edge_paths"]){
                task_base.edge_paths.push_back(Json2TaskPath(path_json));
            }
        }
        else{
            Json::Value parser_data = String2JsonValue(json_data["edge_paths"].asString());
            for(auto& path_json : parser_data){
                task_base.edge_paths.push_back(Json2TaskPath(path_json));
            }
        }
    }
    // cout << "[Json2TaskBase] edge_paths" << endl;
    if(CheckJsonItemIsValid(json_data, "pose")){
        if(json_data["pose"].isObject()){
            task_base.pose = Json2Pose(json_data["pose"]);
        }
        else{
            Json::Value parser_data = String2JsonValue(json_data["pose"].asString());
            task_base.pose = Json2Pose(parser_data);
        }
    }
    if(CheckJsonItemIsValid(json_data, "dynamic_adjust_path")){
        task_base.dynamic_adjust_path = Str2Bool(json_data["dynamic_adjust_path"].asString());
    }
    if(CheckJsonItemIsValid(json_data, "utils_mode")){
        task_base.utils_mode = json_data["utils_mode"].asString();
    }
    if(CheckJsonItemIsValid(json_data, "estimated_time")){
        task_base.estimated_time = stof(json_data["estimated_time"].asString());
    }
    if(CheckJsonItemIsValid(json_data, "estimated_distance")){
        task_base.estimated_distance = stof(json_data["estimated_distance"].asString());
    }
    if(CheckJsonItemIsValid(json_data, "estimated_speed")){
        task_base.estimated_speed = stof(json_data["estimated_speed"].asString());
    }
    if(CheckJsonItemIsValid(json_data, "estimated_efficiency")){
        task_base.estimated_efficiency = stof(json_data["estimated_efficiency"].asString());
    }
    if(CheckJsonItemIsValid(json_data, "task_area")){
        task_base.task_area = stof(json_data["task_area"].asString());
    }
    if(CheckJsonItemIsValid(json_data, "path_gen")){
        if(json_data["path_gen"].isObject()){
            task_base.path_gen = Json2PathGenerate(json_data["path_gen"]);
        }
        else{
            Json::Value parser_data = String2JsonValue(json_data["path_gen"].asString());
            task_base.path_gen = Json2PathGenerate(parser_data);
        }
    }
    if(CheckJsonItemIsValid(json_data, "is_top")){
        task_base.is_top = Str2Bool(json_data["is_top"].asString());
    }
    if(CheckJsonItemIsValid(json_data, "is_assigned")){
        task_base.is_assigned = Str2Bool(json_data["is_assigned"].asString());
    }
    return task_base;
}

// v3_msgs::ErrorCode -> Json::Value
Json::Value MsgConvert::ErrorCode2Json(v3_msgs::ErrorCode& error_code){
    Json::Value json_data;
    Json::Int64 temp = error_code.error_code;
    json_data["error_code"] = temp;
    json_data["error_msg"] = error_code.error_msg;
    return json_data;
}

// Json::Value -> v3_msgs::ErrorCode
v3_msgs::ErrorCode MsgConvert::Json2ErrorCode(Json::Value& json_data){
    v3_msgs::ErrorCode error_code;
    if(CheckJsonItemIsValid(json_data, "error_code")){
        string error_code_str = json_data["error_code"].asString();
        error_code.error_code = stol(error_code_str);
    }
    if(CheckJsonItemIsValid(json_data, "error_msg")){
        error_code.error_msg = json_data["error_msg"].asString();
    }
    return error_code;
}

// TaskPicture -> Json::Value
Json::Value MsgConvert::TaskPicture2Json(TaskPicture& task_picture){
    Json::Value json_data;
    json_data["png_file_path"] = task_picture.png_file_path;
    json_data["png_str"] = task_picture.png_str;
    json_data["qiniu_file_key"] = task_picture.qiniu_file_key;
    json_data["map_name"] = task_picture.map_name;
    return json_data;
}

// Json::Value -> TaskPicture
TaskPicture MsgConvert::Json2TaskPicture(Json::Value& json_data){
    TaskPicture task_picture;
    if(CheckJsonItemIsValid(json_data, "png_file_path")){
        task_picture.png_file_path = json_data["png_file_path"].asString();
    }
    if(CheckJsonItemIsValid(json_data, "png_str")){
        task_picture.png_str = json_data["png_str"].asString();
    }
    if(CheckJsonItemIsValid(json_data, "qiniu_file_key")){
        task_picture.qiniu_file_key = json_data["qiniu_file_key"].asString();
    }
    if(CheckJsonItemIsValid(json_data, "map_name")){
        task_picture.qiniu_file_key = json_data["map_name"].asString();
    }
    return task_picture;
}

// TaskEcho -> Json::Value
Json::Value MsgConvert::TaskEcho2Json(TaskEcho& task_echo){
    Json::Value json_data;
    json_data["task_name"] = task_echo.task_name;
    json_data["task_id"] = task_echo.task_id;
    json_data["add_time"] = task_echo.add_time;
    json_data["start_time"] = task_echo.start_time;
    json_data["end_time"] = task_echo.end_time;
    json_data["progress"] = task_echo.progress;
    json_data["working_time"] = task_echo.working_time;
    json_data["coverage_rate"] = task_echo.coverage_rate;
    json_data["cleaned_area"] = task_echo.cleaned_area;
    json_data["real_average_speed"] = task_echo.real_average_speed;
    json_data["real_travel_dist"] = task_echo.real_travel_dist;
    json_data["avoidance_obstacle_number"] = task_echo.avoidance_obstacle_number;
    json_data["extrication_number"] = task_echo.extrication_number;
    json_data["extrication_time"] = task_echo.extrication_time;
    json_data["missed_area"] = task_echo.missed_area;
    json_data["missed_number"] = task_echo.missed_number;
    json_data["missed_time"] = task_echo.missed_time;
    json_data["cleaned_path"] = TaskPath2Json(task_echo.cleaned_path);
    json_data["error_code"] = ErrorCode2Json(task_echo.error_code);
    json_data["task_status"] = TaskState2Str(task_echo.task_status);
    json_data["task_picture"] = TaskPicture2Json(task_echo.task_picture);
    return json_data;
}

// Json::Value -> TaskEcho
TaskEcho MsgConvert::Json2TaskEcho(Json::Value& json_data){
    TaskEcho task_echo;
    if(CheckJsonItemIsValid(json_data, "task_name")){
        task_echo.task_name = json_data["task_name"].asString();
    }
    if(CheckJsonItemIsValid(json_data, "task_id")){
        task_echo.task_id = json_data["task_id"].asString();
    }
    if(CheckJsonItemIsValid(json_data, "add_time")){
        task_echo.add_time = json_data["add_time"].asString();
    }
    if(CheckJsonItemIsValid(json_data, "start_time")){
        task_echo.start_time = json_data["start_time"].asString();
    }
    if(CheckJsonItemIsValid(json_data, "end_time")){
        task_echo.end_time = json_data["end_time"].asString();
    }
    if(CheckJsonItemIsValid(json_data, "progress")){
        task_echo.progress = json_data["progress"].asDouble();
    }
    if(CheckJsonItemIsValid(json_data, "working_time")){
        task_echo.working_time = json_data["working_time"].asDouble();
    }
    if(CheckJsonItemIsValid(json_data, "coverage_rate")){
        task_echo.coverage_rate = json_data["coverage_rate"].asDouble();
    }
    if(CheckJsonItemIsValid(json_data, "cleaned_area")){
        task_echo.cleaned_area = json_data["cleaned_area"].asDouble();
    }
    if(CheckJsonItemIsValid(json_data, "real_average_speed")){
        task_echo.real_average_speed = json_data["real_average_speed"].asDouble();
    }
    if(CheckJsonItemIsValid(json_data, "real_travel_dist")){
        task_echo.real_travel_dist = json_data["real_travel_dist"].asDouble();
    }
    if(CheckJsonItemIsValid(json_data, "avoidance_obstacle_number")){
        task_echo.avoidance_obstacle_number = json_data["avoidance_obstacle_number"].asDouble();
    }
    if(CheckJsonItemIsValid(json_data, "extrication_number")){
        task_echo.extrication_number = json_data["extrication_number"].asDouble();
    }
    if(CheckJsonItemIsValid(json_data, "extrication_time")){
        task_echo.extrication_time = json_data["extrication_time"].asDouble();
    }
    if(CheckJsonItemIsValid(json_data, "missed_area")){
        task_echo.missed_area = json_data["missed_area"].asDouble();
    }
    if(CheckJsonItemIsValid(json_data, "missed_number")){
        task_echo.missed_number = json_data["missed_number"].asDouble();
    }
    if(CheckJsonItemIsValid(json_data, "missed_time")){
        task_echo.missed_time = json_data["missed_time"].asDouble();
    }
    if(CheckJsonItemIsValid(json_data, "cleaned_path")){
        task_echo.cleaned_path = Json2TaskPath(json_data["cleaned_path"]);
    }
    if(CheckJsonItemIsValid(json_data, "error_code")){
        task_echo.error_code = Json2ErrorCode(json_data["error_code"]);
    }
    if(CheckJsonItemIsValid(json_data, "task_status")){
        task_echo.task_status = Str2TaskState(json_data["task_status"].asString());
    }
    if(CheckJsonItemIsValid(json_data, "task_picture")){
        task_echo.task_picture = Json2TaskPicture(json_data["task_picture"]);
    }
    return task_echo;
}

// TaskSingle -> Json::Value
Json::Value MsgConvert::TaskSingle2Json(TaskSingle& task_single){
    Json::Value json_data;
    json_data["task_base"] = TaskBase2Json(task_single.task_base);
    json_data["task_echo"] = TaskEcho2Json(task_single.task_echo);
    return json_data;    
}

// Json::Value -> TaskSingle
TaskSingle MsgConvert::Json2TaskSingle(Json::Value& json_data){
    TaskSingle task_single;
    // cout << "[Json2TaskSingle] ...... " << endl;
    if(CheckJsonItemIsValid(json_data, "task_base")){
        task_single.task_base = Json2TaskBase(json_data["task_base"]);
    }
    else{
        task_single.task_base = Json2TaskBase(json_data);
    }    
    // cout << "[Json2TaskSingle] task_base " << endl;
    if(CheckJsonItemIsValid(json_data, "task_echo")){
        Json::Value task_echo_json = json_data["task_echo"].isObject() ?
            json_data["task_echo"] : String2JsonValue(json_data["task_echo"].asString());
        task_single.task_echo = Json2TaskEcho(task_echo_json);
    }
    // cout << "[Json2TaskSingle] task_echo " << endl;
    return task_single;
}

// TaskGroup -> Json::Value
Json::Value MsgConvert::TaskGroup2Json(TaskGroup& task_group){
    Json::Value json_data;
    json_data["group_name"] = task_group.group_name;
    json_data["group_id"] = task_group.group_id;
    json_data["timertask_name"] = task_group.timertask_name;
    json_data["timertask_id"] = task_group.timertask_id;
    Json::Value task_list_json;
    for(auto& task_single : task_group.task_list){
        task_list_json.append(TaskSingle2Json(task_single));
    }
    json_data["task_list"] = task_list_json;
    json_data["is_top"] = Bool2Str(task_group.is_top);
    return json_data;    
}

// Json::Value -> TaskGroup
TaskGroup MsgConvert::Json2TaskGroup(Json::Value& json_data){
    TaskGroup task_group;
    if(CheckJsonItemIsValid(json_data, "group_name")){
        task_group.group_name = json_data["group_name"].asString();
    }
    if(CheckJsonItemIsValid(json_data, "group_id")){
        task_group.group_id = json_data["group_id"].asString();
    }
    if(CheckJsonItemIsValid(json_data, "timertask_name")){
        task_group.timertask_name = json_data["timertask_name"].asString();
    }
    if(CheckJsonItemIsValid(json_data, "timertask_id")){
        task_group.timertask_id = json_data["timertask_id"].asString();
    }
    // cout << "[Json2TaskGroup] timertask_id " << endl;
    if(CheckJsonItemIsValid(json_data, "task_list")){
        // cout << "[Json2TaskGroup] task_list_json: " << json_data["task_list"].asString() << endl;
        // cout << "[Json2TaskGroup] isArray:" << json_data["task_list"].isArray() << endl;
        // cout << "[Json2TaskGroup] isObject:" << json_data["task_list"].isObject() << endl;
        Json::Value task_list_json = json_data["task_list"].isArray() ?
            json_data["task_list"] : String2JsonValue(json_data["task_list"].asString());
        // cout << "[Json2TaskGroup] task_list_json: " << task_list_json.size() << endl;
        for(auto& item : task_list_json){
            // cout << "item: " << item << endl;
            task_group.task_list.emplace_back(Json2TaskSingle(item));
        }
    }
    // cout << "[Json2TaskGroup] task_list " << endl;
    if(CheckJsonItemIsValid(json_data, "is_top")){
        task_group.is_top = Str2Bool(json_data["is_top"].asString());
    }
    return task_group;       
}


// TimerTask -> Json::Value
Json::Value MsgConvert::TimerTask2Json(TimerTask& timer_task){
    Json::Value json_data;
    json_data["timertask_name"] = timer_task.timertask_name;
    json_data["timertask_id"] = timer_task.timertask_id;
    json_data["enable"] = Bool2Str(timer_task.enable);
    json_data["start_time"] = timer_task.start_time;
    json_data["forced_end_time"] = timer_task.forced_end_time;
    json_data["timetable"] = IntVector2Json(timer_task.timetable);
    json_data["forced_end_time_enable"] = Bool2Str(timer_task.forced_end_time_enable);
    Json::Value taskgroup_list_json;
    for(auto& task_group : timer_task.taskgroup_list){
        taskgroup_list_json.append(TaskGroup2Json(task_group));
    }
    json_data["taskgroup_list"] = taskgroup_list_json;
    json_data["estimated_time"] = timer_task.estimated_time;
    json_data["is_top"] = Bool2Str(timer_task.is_top);
    json_data["multi_maps_shared"] = Bool2Str(timer_task.multi_maps_shared);
    json_data["map_name"] = timer_task.map_name;
    return json_data;    
}

// Json::Value -> TimerTask
TimerTask MsgConvert::Json2TimerTask(Json::Value& json_data){
    TimerTask timer_task;
    if(CheckJsonItemIsValid(json_data, "timertask_name")){
        timer_task.timertask_name = json_data["timertask_name"].asString();
    }
    if(CheckJsonItemIsValid(json_data, "timertask_id")){
        timer_task.timertask_id = json_data["timertask_id"].asString();
    }
    if(CheckJsonItemIsValid(json_data, "enable")){
        timer_task.enable = Str2Bool(json_data["enable"].asString());
    }
    if(CheckJsonItemIsValid(json_data, "start_time")){
        timer_task.start_time = json_data["start_time"].asString();
    }
    if(CheckJsonItemIsValid(json_data, "forced_end_time")){
        timer_task.forced_end_time = json_data["forced_end_time"].asString();
    }
    if(CheckJsonItemIsValid(json_data, "forced_end_time_enable")){
        timer_task.forced_end_time_enable = Str2Bool(json_data["forced_end_time_enable"].asString());
    }
    if(CheckJsonItemIsValid(json_data, "timetable")){
        Json::Value timetable_json = json_data["timetable"].isObject() ?
            json_data["timetable"] : String2JsonValue(json_data["timetable"].asString());
        timer_task.timetable = Json2IntVector(timetable_json);
    }
    if(CheckJsonItemIsValid(json_data, "taskgroup_list")){
        Json::Value taskgroup_list_json = json_data["taskgroup_list"].isArray() ?
            json_data["taskgroup_list"] : String2JsonValue(json_data["taskgroup_list"].asString());
        for(auto& item : taskgroup_list_json){
            timer_task.taskgroup_list.emplace_back(Json2TaskGroup(item));
        }
    }
    if(CheckJsonItemIsValid(json_data, "estimated_time")){
        timer_task.estimated_time = stof(json_data["estimated_time"].asString());
    }
    if(CheckJsonItemIsValid(json_data, "is_top")){
        timer_task.is_top = Str2Bool(json_data["is_top"].asString());
    }
    if(CheckJsonItemIsValid(json_data, "multi_maps_shared")){
        timer_task.multi_maps_shared = Str2Bool(json_data["multi_maps_shared"].asString());
    }
    if(CheckJsonItemIsValid(json_data, "map_name")){
        timer_task.map_name = json_data["map_name"].asString();
    }
    return timer_task;       
}

// TaskRecord -> Json::Value
Json::Value MsgConvert::TaskRecord2Json(TaskRecord& task_record){
    Json::Value json_data;
    json_data["task_group"] = TaskGroup2Json(task_record.task_group);
    json_data["is_assigned"] = Bool2Str(task_record.is_assigned);
    json_data["start_time"] = task_record.start_time;
    json_data["end_time"] = task_record.end_time;
    json_data["working_time"] = task_record.working_time;
    json_data["total_area"] = task_record.total_area;
    json_data["cleaned_area"] = task_record.cleaned_area;
    json_data["uncleaned_area"] = task_record.uncleaned_area;
    json_data["cleaning_efficiency"] = task_record.cleaning_efficiency;
    json_data["coverage_rate"] = task_record.coverage_rate;
    json_data["error_code"] = ErrorCode2Json(task_record.error_code);
    Json::Value task_pictures_json;
    for(auto& item : task_record.task_pictures){
        task_pictures_json.append(TaskPicture2Json(item));
    }
    json_data["task_pictures"] = task_pictures_json;
    json_data["status"] = TaskState2Str(task_record.status);
    return json_data;    
}

// Json::Value -> TaskRecord
TaskRecord MsgConvert::Json2TaskRecord(Json::Value& json_data){
    TaskRecord task_record;
    if(CheckJsonItemIsValid(json_data, "task_group")){
        Json::Value task_group_json = json_data["task_group"].isObject() ?
            json_data["task_group"] : String2JsonValue(json_data["task_group"].asString());
        task_record.task_group = Json2TaskGroup(task_group_json);
    }
    if(CheckJsonItemIsValid(json_data, "start_time")){
        task_record.start_time = json_data["start_time"].asString();
    }
    if(CheckJsonItemIsValid(json_data, "end_time")){
        task_record.end_time = json_data["end_time"].asString();
    }
    if(CheckJsonItemIsValid(json_data, "working_time")){
        task_record.working_time = stof(json_data["working_time"].asString());
    }
    if(CheckJsonItemIsValid(json_data, "total_area")){
        task_record.total_area = stof(json_data["total_area"].asString());
    }
    if(CheckJsonItemIsValid(json_data, "cleaned_area")){
        task_record.cleaned_area = stof(json_data["cleaned_area"].asString());
    }
    if(CheckJsonItemIsValid(json_data, "uncleaned_area")){
        task_record.uncleaned_area = stof(json_data["uncleaned_area"].asString());
    }
    if(CheckJsonItemIsValid(json_data, "cleaning_efficiency")){
        task_record.cleaning_efficiency = stof(json_data["cleaning_efficiency"].asString());
    }
    if(CheckJsonItemIsValid(json_data, "coverage_rate")){
        task_record.coverage_rate = stof(json_data["coverage_rate"].asString());
    }
    if(CheckJsonItemIsValid(json_data, "error_code")){
        Json::Value error_code_json = json_data["error_code"].isObject() ?
            json_data["error_code"] : String2JsonValue(json_data["error_code"].asString());
        task_record.error_code = Json2ErrorCode(error_code_json);
    }
    if(CheckJsonItemIsValid(json_data, "task_pictures")){
        Json::Value task_pictures = json_data["task_pictures"].isArray() ?
            json_data["task_pictures"] : String2JsonValue(json_data["task_pictures"].asString());
        for(auto& item : task_pictures){
            task_record.task_pictures.emplace_back(Json2TaskPicture(item));
        }
    }
    if(CheckJsonItemIsValid(json_data, "status")){
        task_record.status = Str2TaskState(json_data["status"].asString());
    }
    if(CheckJsonItemIsValid(json_data, "is_assigned")){
        // cout << "[Json2TaskRecord] is_assigned: " << endl;
        string is_assigned_str = json_data["is_assigned"].asString();
        if(is_assigned_str.empty()){
            // 新增数据兼容，如果为空且覆盖率大于0.1，可认为已指派下发
            task_record.is_assigned = task_record.coverage_rate > 0.1 ? true : false;
        }
        else{
            task_record.is_assigned = Str2Bool(json_data["is_assigned"].asString());
        }
        
    }
    else{
        // 新增数据兼容，如果为空且覆盖率大于0.1，可认为已指派下发
        task_record.is_assigned = task_record.coverage_rate > 0.1 ? true : false;
    }
    return task_record;       
}


/*******************************************
* msg_convert
* 消息兼容转换
*******************************************/
// v3_msgs::PolygonData -> geometry_msgs::Polygon
geometry_msgs::Polygon MsgConvert::PolygonData2PolygonMsg(v3_msgs::PolygonData& polygon){
    geometry_msgs::Polygon polygon_msg;
    for(auto& pose : polygon.poses){
        geometry_msgs::Point32 point;
        point.x = pose.position.x;
        point.y = pose.position.y;
        point.z = pose.position.z;
        polygon_msg.points.emplace_back(point);
    }
    return polygon_msg;
}

// geometry_msgs::Polygon -> v3_msgs::PolygonData
v3_msgs::PolygonData MsgConvert::PolygonMsg2PolygonData(geometry_msgs::Polygon& polygon){
    v3_msgs::PolygonData polygon_data;
    for(auto&point : polygon.points){
        geometry_msgs::Pose pose;
        pose.position.x = point.x;
        pose.position.y = point.y;
        pose.position.z = point.z;
        polygon_data.poses.emplace_back(pose);
    }
    return polygon_data;
}

// TaskBase -> cln_msgs::CleanTask
cln_msgs::CleanTask MsgConvert::TaskBase2CleanTask(TaskBase& task_base){
    cln_msgs::CleanTask clean_task;
    // 创建任务时属性
    clean_task.task_name = task_base.task_name;
    clean_task.map_name = task_base.map_base.name;
    clean_task.path_start = task_base.start.position;
    clean_task.global_area = PolygonData2PolygonMsg(task_base.polygon);
    clean_task.type = task_base.dynamic_adjust_path ? clean_task.DYNAMIC : clean_task.STATIC;
    // global_spd
    switch(task_base.task_speed){
        case TaskSpeed::LOW_SPEED:
            clean_task.global_spd = clean_task.LOW_SPEED;
            break;
        case TaskSpeed::MIDDLE_SPEED:
            clean_task.global_spd = clean_task.MID_SPEED;
            break;
        case TaskSpeed::HIGH_SPEED:
            clean_task.global_spd = clean_task.HIGH_SPEED;
            break;
        default:
            clean_task.global_spd = clean_task.LOW_SPEED;
            break;
    }
    // clean_mode
    PathGenerateType path_types_front = task_base.path_gen.path_types.empty() ? 
            PathGenerateType::UNKNOWN : task_base.path_gen.path_types.front();
    PathGenerateType path_types_child_front = task_base.path_gen.path_types_child.empty() ? 
            PathGenerateType::UNKNOWN : task_base.path_gen.path_types_child.front();     
    if(task_base.task_type == TaskType::CHARGING_TASK){
        clean_task.clean_mode = clean_task.CHARGE;
    }
    else if(task_base.task_type == TaskType::P2P_TASK){
        clean_task.clean_mode = clean_task.P2P;
    }
    else if(task_base.task_type == TaskType::TEACH_TASK){
        clean_task.clean_mode = clean_task.FOLLOW_TEACH;
    }
    else if(task_base.task_type == TaskType::SWEEP_TASK){
        switch (task_base.control_mode){
        case TaskControlMode::SWEEP_STANDARD_MODE:  // NORM_SWEEP/ROUND_SWEEP
            if(path_types_front == PathGenerateType::BOUSTROPHEDON_METHOD){
                clean_task.clean_mode = clean_task.NORM_SWEEP;
            }
            if(path_types_front == PathGenerateType::WRAPPER_METHOD){
                clean_task.clean_mode = clean_task.ROUND_SWEEP;
            }
            break;
        case TaskControlMode::SWEEP_EDGE_MODE:
            clean_task.clean_mode = clean_task.PERIMETER_SWEEP;
            break;
        case TaskControlMode::SWEEP_STANDARD_AND_EDGE:      // NROM_PERI/ROUND_PERI
            if(path_types_front == PathGenerateType::BOUSTROPHEDON_METHOD){
                clean_task.clean_mode = clean_task.NROM_PERI;
            }
            if(path_types_front == PathGenerateType::WRAPPER_METHOD){
                clean_task.clean_mode = clean_task.ROUND_PERI;
            }
            break;
        case TaskControlMode::FOLLOW_MODE:
            clean_task.clean_mode = clean_task.FOLLOW_TEACH;
            break;
        default:
            break;
        }
    }
    else if(task_base.task_type == TaskType::ELEVATOR_TRANS_TASK){
        clean_task.clean_mode = clean_task.FLOOR_TRANS;
    }
    clean_task.device_mode = clean_task.SWEEP;
    clean_task.clean_mode_name = task_base.utils_mode;
    for(auto& polygon : task_base.path_gen.danger_areas){
        clean_task.danger_areas.emplace_back(PolygonData2PolygonMsg(polygon));
    }
    // 保存任务时属性

    // 运行任务时属性

    return clean_task;
}

// cln_msgs::CleanTask -> TaskBase
TaskBase MsgConvert::CleanTask2TaskBase(cln_msgs::CleanTask& clean_task){
    TaskBase task_base;
    cout << "[CleanTask2TaskBase] ................ theoretic_cov_rate: " << clean_task.theoretic_cov_rate << endl;
    // 创建任务时属性
    task_base.task_area = clean_task.theoretic_cov_rate;

    return task_base;
}


// cln_msgs::CleanTask -> TaskGenerate
TaskSingle MsgConvert::CleanTask2TaskSingle(cln_msgs::CleanTask& clean_task){
    TaskSingle task_single;
    task_single.task_base = CleanTask2TaskBase(clean_task);
    for(auto&task_meta : clean_task.subtasks){
        TaskPath task_path = TaskMeta2TaskPath(task_meta);
        if(task_path.path_type == PathGenerateType::EDGE_METHOD){
            task_single.task_base.edge_paths.emplace_back(task_path);
        }
        else{
            task_single.task_base.paths.emplace_back(task_path);
        }
    }
    task_single.task_base.edge_mode = EdgeMode::EDGE_ZERO_MODE;
    // 待补充，控制模式需要填写
    return task_single;
}

// cln_msgs::TaskMeta -> TaskPath
TaskPath MsgConvert::TaskMeta2TaskPath(cln_msgs::TaskMeta& task_meta){
    TaskPath task_path;
    TaskControlMode control_mode;
    task_path.path_interval = task_meta.path_width;
    for(auto&pose_stamp : task_meta.path.poses){
        task_path.poses.emplace_back(pose_stamp.pose);
    }
    task_path.path_type = task_meta.sweep_mode == task_meta.PERIMETER_CLEAN ? 
        PathGenerateType::EDGE_METHOD : PathGenerateType::UNKNOWN;
    return task_path;
}